/* 
 * More info at: http://phpjs.org
 * 
 * This is version: 3.06
 * php.js is copyright 2010 Kevin van Zonneveld.
 * 
 * Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld
 * (http://kevin.vanzonneveld.net), Onno Marsman, Michael White
 * (http://getsprink.com), Theriault, Waldo Malqui Silva, Paulo Ricardo F.
 * Santos, Jack, Jonas Raoni Soares Silva (http://www.jsfromhell.com), Philip
 * Peterson, Legaev Andrey, Ates Goral (http://magnetiq.com), Alex, Ratheous,
 * Martijn Wieringa, Nate, Philippe Baumann, lmeyrick
 * (https://sourceforge.net/projects/bcmath-js/), Enrique Gonzalez,
 * Webtoolkit.info (http://www.webtoolkit.info/), Jani Hartikainen, Ole
 * Vrijenhoek, Carlos R. L. Rodrigues (http://www.jsfromhell.com), Ash Searle
 * (http://hexmen.com/blog/), travc, stag019, pilus, T.Wild,
 * http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript,
 * Johnny Mast (http://www.phpvrouwen.nl), Erkekjetter, WebDevHobo
 * (http://webdevhobo.blogspot.com/), GeekFG (http://geekfg.blogspot.com),
 * Andrea Giammarchi (http://webreflection.blogspot.com), d3x, marrtins,
 * Michael Grier, Mirek Slugen, majak, mdsjack (http://www.mdsjack.bo.it),
 * gettimeofday, Mailfaker (http://www.weedem.fr/), David, Michael White,
 * Public Domain (http://www.json.org/json2.js), Tim de Koning
 * (http://www.kingsquare.nl), Oleg Eremeev, Marc Palau, Steven Levithan
 * (http://blog.stevenlevithan.com), Josh Fraser
 * (http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/),
 * KELAN, Arpad Ray (mailto:arpad@php.net), Joris, Breaking Par Consulting Inc
 * (http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7),
 * Martin (http://www.erlenwiese.de/), AJ, Lars Fischer, Felix Geisendoerfer
 * (http://www.debuggable.com/felix), Pellentesque Malesuada, Caio Ariede
 * (http://caioariede.com), Kankrelune (http://www.webfaktory.info/), Alfonso
 * Jimenez (http://www.alfonsojimenez.com), Sakimori, Steve Hilder, gorthaur,
 * Aman Gupta, Karol Kowalski, Thunder.m, Tyler Akins (http://rumkin.com),
 * john (http://www.jd-tech.net), Douglas Crockford
 * (http://javascript.crockford.com), mktime, Gilbert, Marco, paulo kuong,
 * Frank Forte, duncan, madipta, ger, Subhasis Deb, felix, Denny Wardhana,
 * Mateusz "loonquawl" Zalega, ReverseSyntax, Francois, Scott Cariss, Slawomir
 * Kaniecki, Arno, Nathan, Nick Kolosov (http://sammy.ru), 0m3r, noname, marc
 * andreu, Fox, sankai, Sanjoy Roy, nobbler, Steve Clay, class_exists, Thiago
 * Mata (http://thiagomata.blog.com), Jon Hohle, nord_ua, Ozh, echo is bad,
 * Linuxworld, XoraX (http://www.xorax.info), Pyerre, Soren Hansen, Brad
 * Touesnard, MeEtc (http://yass.meetcweb.com), Tim Wiel, Bryan Elliott,
 * T0bsn, Peter-Paul Koch (http://www.quirksmode.org/js/beat.html), David
 * Randall, Der Simon (http://innerdom.sourceforge.net/), lmeyrick
 * (https://sourceforge.net/projects/bcmath-js/this.), Hyam Singer
 * (http://www.impact-computing.com/), Paul, kenneth, Raphael (Ao RUDLER),
 * David James, T. Wild, Ole Vrijenhoek (http://www.nervous.nl/), J A R,
 * Bayron Guevara, LH, JB, Eugene Bulkin (http://doubleaw.com/), Stoyan Kyosev
 * (http://www.svest.org/), djmix, Marc Jansen, Francesco, Lincoln Ramsay,
 * Manish, date, Kristof Coomans (SCK-CEN Belgian Nucleair Research Centre),
 * Pierre-Luc Paour, Martin Pool, Rick Waldron, Kirk Strobeck, Saulo Vallory,
 * Christoph, Artur Tchernychev, Wagner B. Soares, Valentina De Rosa, Daniel
 * Esteban, Jason Wong (http://carrot.org/), Mick@el, rezna, Simon Willison
 * (http://simonwillison.net), Gabriel Paderni, Marco van Oort,
 * penutbutterjelly, Philipp Lenssen, Anton Ongson, Blues
 * (http://tech.bluesmoon.info/), Tomasz Wesolowski, Eric Nagel, Bobby Drake,
 * Luke Godfrey, Pul, uestla, Alan C, Yves Sucaet, sowberry, hitwork, Orlando,
 * Norman "zEh" Fuchs, Ulrich, johnrembo, Nick Callen, ejsanders, Aidan Lister
 * (http://aidanlister.com/), Brian Tafoya (http://www.premasolutions.com/),
 * Philippe Jausions (http://pear.php.net/user/jausions), kilops, dptr1988,
 * HKM, metjay, strcasecmp, strcmp, Taras Bogach, jpfle, ChaosNo1, Alexander
 * Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev), Le Torbi,
 * James, Chris, DxGx, Pedro Tainha (http://www.pedrotainha.com), Christian
 * Doebler, setcookie, Greg Frazier, Tod Gentille, Alexander M Beedie,
 * FremyCompany, T.J. Leahy, baris ozdil, FGFEmperor, daniel airton wermann
 * (http://wermann.com.br), 3D-GRAF, jakes, gabriel paderni, Yannoo, Luis
 * Salazar (http://www.freaky-media.com/), Tim de Koning, stensi, Billy, vlado
 * houba, Itsacon (http://www.itsacon.net/), Jalal Berrami, Matteo, Victor,
 * taith, Robin, Matt Bradley, fearphage
 * (http://http/my.opera.com/fearphage/), Cord, Atli Þór, Maximusya, Andrej
 * Pavlovic, Dino, rem, Greenseed, meo, Garagoth, Russell Walker
 * (http://www.nbill.co.uk/), YUI Library:
 * http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Blues at
 * http://hacks.bluesmoon.info/strftime/strftime.js, Andreas, Jamie Beck
 * (http://www.terabit.ca/), DtTvB
 * (http://dt.in.th/2008-09-16.string-length-in-bytes.html), mk.keck, Leslie
 * Hoare, Diogo Resende, Howard Yeend, Allan Jensen (http://www.winternet.no),
 * davook, Benjamin Lupton, Rival, Luke Smith (http://lucassmith.name),
 * booeyOH, Ben Bryan, Cagri Ekin, Amir Habibi
 * (http://www.residence-mixte.com/), Kheang Hok Chin
 * (http://www.distantia.ca/), Jay Klehr
 * 
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */ 


// jslint.com configuration options: see http://jslint.com/
/*jslint evil: true, forin: true, newcap: true*/
/*global window */
(function() {
    if(typeof(this.PHP_JS) === "undefined"){ 
        // This references at top of namespace allows PHP_JS class to
        // be included directly inside an object (unusual use)
        var PHP_JS = function(cfgObj) {
            if(!(this instanceof PHP_JS)) {
                // Allow invokation without "new"
                return new PHP_JS(cfgObj);
            }
            // Allow user to pass in window, e.g., if in context
            // without access to window but need to pass in, like
            // a Mozilla JavaScript module
            this.window = cfgObj && cfgObj.window ? cfgObj.window : window;

            // Allow user to pass in object representing initial ini values
            this.php_js = {};
            this.php_js.ini = {};
            if (cfgObj) {
                for (var ini in cfgObj.ini) {
                    this.php_js.ini[ini] = {};
                    this.php_js.ini[ini].local_value = cfgObj.ini[ini]; // changeable by ini_set()
                    this.php_js.ini[ini].global_value = cfgObj.ini[ini]; // usable by ini_restore()
                }
            }
        };
    }
    // Private static holder across all instances; we usually use
    // instance variables, but this is necessary for a very few
    // like require_once()/include_once()
    var php_js_shared = {};

    PHP_JS.prototype = {
        constructor: PHP_JS,
        get_html_translation_table: function (table, quote_style) {
            // Returns the internal translation table used by htmlspecialchars and htmlentities  
            // 
            // version: 909.322
            // discuss at: http://phpjs.org/functions/get_html_translation_table
            // +   original by: Philip Peterson
            // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   bugfixed by: noname
            // +   bugfixed by: Alex
            // +   bugfixed by: Marco
            // +   bugfixed by: madipta
            // +   improved by: KELAN
            // +   improved by: Brett Zamir (http://brett-zamir.me)
            // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
            // +      input by: Frank Forte
            // +   bugfixed by: T.Wild
            // +      input by: Ratheous
            // %          note: It has been decided that we're not going to add global
            // %          note: dependencies to php.js, meaning the constants are not
            // %          note: real constants, but strings instead. Integers are also supported if someone
            // %          note: chooses to create the constants themselves.
            // *     example 1: $P.get_html_translation_table('HTML_SPECIALCHARS');
            // *     returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
            
            var entities = {}, hash_map = {}, decimal = 0, symbol = '';
            var constMappingTable = {}, constMappingQuoteStyle = {};
            var useTable = {}, useQuoteStyle = {};
            
            // Translate arguments
            constMappingTable[0]      = 'HTML_SPECIALCHARS';
            constMappingTable[1]      = 'HTML_ENTITIES';
            constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
            constMappingQuoteStyle[2] = 'ENT_COMPAT';
            constMappingQuoteStyle[3] = 'ENT_QUOTES';
        
            useTable       = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
            useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';
        
            if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
                throw new Error("Table: "+useTable+' not supported');
                // return false;
            }
        
            entities['38'] = '&amp;';
            if (useTable === 'HTML_ENTITIES') {
                entities['160'] = '&nbsp;';
                entities['161'] = '&iexcl;';
                entities['162'] = '&cent;';
                entities['163'] = '&pound;';
                entities['164'] = '&curren;';
                entities['165'] = '&yen;';
                entities['166'] = '&brvbar;';
                entities['167'] = '&sect;';
                entities['168'] = '&uml;';
                entities['169'] = '&copy;';
                entities['170'] = '&ordf;';
                entities['171'] = '&laquo;';
                entities['172'] = '&not;';
                entities['173'] = '&shy;';
                entities['174'] = '&reg;';
                entities['175'] = '&macr;';
                entities['176'] = '&deg;';
                entities['177'] = '&plusmn;';
                entities['178'] = '&sup2;';
                entities['179'] = '&sup3;';
                entities['180'] = '&acute;';
                entities['181'] = '&micro;';
                entities['182'] = '&para;';
                entities['183'] = '&middot;';
                entities['184'] = '&cedil;';
                entities['185'] = '&sup1;';
                entities['186'] = '&ordm;';
                entities['187'] = '&raquo;';
                entities['188'] = '&frac14;';
                entities['189'] = '&frac12;';
                entities['190'] = '&frac34;';
                entities['191'] = '&iquest;';
                entities['192'] = '&Agrave;';
                entities['193'] = '&Aacute;';
                entities['194'] = '&Acirc;';
                entities['195'] = '&Atilde;';
                entities['196'] = '&Auml;';
                entities['197'] = '&Aring;';
                entities['198'] = '&AElig;';
                entities['199'] = '&Ccedil;';
                entities['200'] = '&Egrave;';
                entities['201'] = '&Eacute;';
                entities['202'] = '&Ecirc;';
                entities['203'] = '&Euml;';
                entities['204'] = '&Igrave;';
                entities['205'] = '&Iacute;';
                entities['206'] = '&Icirc;';
                entities['207'] = '&Iuml;';
                entities['208'] = '&ETH;';
                entities['209'] = '&Ntilde;';
                entities['210'] = '&Ograve;';
                entities['211'] = '&Oacute;';
                entities['212'] = '&Ocirc;';
                entities['213'] = '&Otilde;';
                entities['214'] = '&Ouml;';
                entities['215'] = '&times;';
                entities['216'] = '&Oslash;';
                entities['217'] = '&Ugrave;';
                entities['218'] = '&Uacute;';
                entities['219'] = '&Ucirc;';
                entities['220'] = '&Uuml;';
                entities['221'] = '&Yacute;';
                entities['222'] = '&THORN;';
                entities['223'] = '&szlig;';
                entities['224'] = '&agrave;';
                entities['225'] = '&aacute;';
                entities['226'] = '&acirc;';
                entities['227'] = '&atilde;';
                entities['228'] = '&auml;';
                entities['229'] = '&aring;';
                entities['230'] = '&aelig;';
                entities['231'] = '&ccedil;';
                entities['232'] = '&egrave;';
                entities['233'] = '&eacute;';
                entities['234'] = '&ecirc;';
                entities['235'] = '&euml;';
                entities['236'] = '&igrave;';
                entities['237'] = '&iacute;';
                entities['238'] = '&icirc;';
                entities['239'] = '&iuml;';
                entities['240'] = '&eth;';
                entities['241'] = '&ntilde;';
                entities['242'] = '&ograve;';
                entities['243'] = '&oacute;';
                entities['244'] = '&ocirc;';
                entities['245'] = '&otilde;';
                entities['246'] = '&ouml;';
                entities['247'] = '&divide;';
                entities['248'] = '&oslash;';
                entities['249'] = '&ugrave;';
                entities['250'] = '&uacute;';
                entities['251'] = '&ucirc;';
                entities['252'] = '&uuml;';
                entities['253'] = '&yacute;';
                entities['254'] = '&thorn;';
                entities['255'] = '&yuml;';
            }
        
            if (useQuoteStyle !== 'ENT_NOQUOTES') {
                entities['34'] = '&quot;';
            }
            if (useQuoteStyle === 'ENT_QUOTES') {
                entities['39'] = '&#39;';
            }
            entities['60'] = '&lt;';
            entities['62'] = '&gt;';
        
        
            // ascii decimals to real symbols
            for (decimal in entities) {
                symbol = String.fromCharCode(decimal);
                hash_map[symbol] = entities[decimal];
            }
            
            return hash_map;
        }
        ,
        htmlentities: function (string, quote_style) {
            // Convert all applicable characters to HTML entities  
            // 
            // version: 909.322
            // discuss at: http://phpjs.org/functions/htmlentities
            // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   improved by: nobbler
            // +    tweaked by: Jack
            // +   bugfixed by: Onno Marsman
            // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
            // +      input by: Ratheous
            // -    depends on: get_html_translation_table
            // *     example 1: $P.htmlentities('Kevin & van Zonneveld');
            // *     returns 1: 'Kevin &amp; van Zonneveld'
            // *     example 2: $P.htmlentities("foo'bar","ENT_QUOTES");
            // *     returns 2: 'foo&#039;bar'
            var hash_map = {}, symbol = '', tmp_str = '', entity = '';
            tmp_str = string.toString();
            
            if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
                return false;
            }
            hash_map["'"] = '&#039;';
            for (symbol in hash_map) {
                entity = hash_map[symbol];
                tmp_str = tmp_str.split(symbol).join(entity);
            }
            
            return tmp_str;
        }
        ,
        htmlspecialchars: function (string, quote_style, charset, double_encode) {
            // Convert special characters to HTML entities  
            // 
            // version: 912.1315
            // discuss at: http://phpjs.org/functions/htmlspecialchars
            // +   original by: Mirek Slugen
            // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   bugfixed by: Nathan
            // +   bugfixed by: Arno
            // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
            // +      input by: Ratheous
            // +      input by: Mailfaker (http://www.weedem.fr/)
            // +      reimplemented by: Brett Zamir (http://brett-zamir.me)
            // +      input by: felix
            // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
            // %        note 1: charset argument not supported
            // *     example 1: $P.htmlspecialchars("<a href='test'>Test</a>", 'ENT_QUOTES');
            // *     returns 1: '&lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;'
            // *     example 2: $P.htmlspecialchars("ab\"c'd", ['ENT_NOQUOTES', 'ENT_QUOTES']);
            // *     returns 2: 'ab"c&#039;d'
            // *     example 3: $P.htmlspecialchars("my "&entity;" is still here", null, null, false);
            // *     returns 3: 'my &quot;&entity;&quot; is still here'
            var optTemp = 0, i = 0, noquotes= false;
            if (typeof quote_style === 'undefined' || quote_style === null) {
                quote_style = 2;
            }
            string = string.toString();
            if (double_encode !== false) { // Put this first to avoid double-encoding
                string = string.replace(/&/g, '&amp;');
            }
            string = string.replace(/</g, '&lt;').replace(/>/g, '&gt;');
        
            var OPTS = {
                'ENT_NOQUOTES': 0,
                'ENT_HTML_QUOTE_SINGLE' : 1,
                'ENT_HTML_QUOTE_DOUBLE' : 2,
                'ENT_COMPAT': 2,
                'ENT_QUOTES': 3,
                'ENT_IGNORE' : 4
            };
            if (quote_style === 0) {
                noquotes = true;
            }
            if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
                quote_style = [].concat(quote_style);
                for (i=0; i < quote_style.length; i++) {
                    // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
                    if (OPTS[quote_style[i]] === 0) {
                        noquotes = true;
                    }
                    else if (OPTS[quote_style[i]]) {
                        optTemp = optTemp | OPTS[quote_style[i]];
                    }
                }
                quote_style = optTemp;
            }
            if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
                string = string.replace(/'/g, '&#039;');
            }
            if (!noquotes) {
                string = string.replace(/"/g, '&quot;');
            }
        
            return string;
        }
        ,
        htmlspecialchars_decode: function (string, quote_style) {
            // Convert special HTML entities back to characters  
            // 
            // version: 912.1315
            // discuss at: http://phpjs.org/functions/htmlspecialchars_decode
            // +   original by: Mirek Slugen
            // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   bugfixed by: Mateusz "loonquawl" Zalega
            // +      input by: ReverseSyntax
            // +      input by: Slawomir Kaniecki
            // +      input by: Scott Cariss
            // +      input by: Francois
            // +   bugfixed by: Onno Marsman
            // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
            // +      input by: Ratheous
            // +      input by: Mailfaker (http://www.weedem.fr/)
            // +      reimplemented by: Brett Zamir (http://brett-zamir.me)
            // +    bugfixed by: Brett Zamir (http://brett-zamir.me)
            // *     example 1: $P.htmlspecialchars_decode("<p>this -&gt; &quot;</p>", 'ENT_NOQUOTES');
            // *     returns 1: '<p>this -> &quot;</p>'
            // *     example 2: $P.htmlspecialchars_decode("&amp;quot;");
            // *     returns 2: '&quot;'
            var optTemp = 0, i = 0, noquotes= false;
            if (typeof quote_style === 'undefined') {
                quote_style = 2;
            }
            string = string.toString().replace(/&lt;/g, '<').replace(/&gt;/g, '>');
            var OPTS = {
                'ENT_NOQUOTES': 0,
                'ENT_HTML_QUOTE_SINGLE' : 1,
                'ENT_HTML_QUOTE_DOUBLE' : 2,
                'ENT_COMPAT': 2,
                'ENT_QUOTES': 3,
                'ENT_IGNORE' : 4
            };
            if (quote_style === 0) {
                noquotes = true;
            }
            if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
                quote_style = [].concat(quote_style);
                for (i=0; i < quote_style.length; i++) {
                    // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
                    if (OPTS[quote_style[i]] === 0) {
                        noquotes = true;
                    }
                    else if (OPTS[quote_style[i]]) {
                        optTemp = optTemp | OPTS[quote_style[i]];
                    }
                }
                quote_style = optTemp;
            }
            if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
                string = string.replace(/&#0*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
                // string = string.replace(/&apos;|&#x0*27;/g, "'"); // This would also be useful here, but not a part of PHP
            }
            if (!noquotes) {
                string = string.replace(/&quot;/g, '"');
            }
            // Put this in last place to avoid escape being double-decoded
            string = string.replace(/&amp;/g, '&');
        
            return string;
        }
        ,
        nl2br: function (str, is_xhtml) {
            // Converts newlines to HTML line breaks  
            // 
            // version: 911.1619
            // discuss at: http://phpjs.org/functions/nl2br
            // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   improved by: Philip Peterson
            // +   improved by: Onno Marsman
            // +   improved by: Atli Þór
            // +   bugfixed by: Onno Marsman
            // +      input by: Brett Zamir (http://brett-zamir.me)
            // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   improved by: Brett Zamir (http://brett-zamir.me)
            // +   improved by: Maximusya
            // *     example 1: $P.nl2br('Kevin\nvan\nZonneveld');
            // *     returns 1: 'Kevin<br />\nvan<br />\nZonneveld'
            // *     example 2: $P.nl2br("\nOne\nTwo\n\nThree\n", false);
            // *     returns 2: '<br>\nOne<br>\nTwo<br>\n<br>\nThree<br>\n'
            // *     example 3: $P.nl2br("\nOne\nTwo\n\nThree\n", true);
            // *     returns 3: '<br />\nOne<br />\nTwo<br />\n<br />\nThree<br />\n'
            var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';
        
            return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
        }
        ,
        sprintf: function ( ) {
            // Return a formatted string  
            // 
            // version: 909.322
            // discuss at: http://phpjs.org/functions/sprintf
            // +   original by: Ash Searle (http://hexmen.com/blog/)
            // + namespaced by: Michael White (http://getsprink.com)
            // +    tweaked by: Jack
            // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +      input by: Paulo Ricardo F. Santos
            // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +      input by: Brett Zamir (http://brett-zamir.me)
            // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // *     example 1: $P.sprintf("%01.2f", 123.1);
            // *     returns 1: 123.10
            // *     example 2: $P.sprintf("[%10s]", 'monkey');
            // *     returns 2: '[    monkey]'
            // *     example 3: $P.sprintf("[%'#10s]", 'monkey');
            // *     returns 3: '[####monkey]'
            var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g;
            var a = arguments, i = 0, format = a[i++];
        
            // pad()
            var pad = function (str, len, chr, leftJustify) {
                if (!chr) {chr = ' ';}
                var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
                return leftJustify ? str + padding : padding + str;
            };
        
            // justify()
            var justify = function (value, prefix, leftJustify, minWidth, zeroPad, customPadChar) {
                var diff = minWidth - value.length;
                if (diff > 0) {
                    if (leftJustify || !zeroPad) {
                        value = pad(value, minWidth, customPadChar, leftJustify);
                    } else {
                        value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
                    }
                }
                return value;
            };
        
            // formatBaseX()
            var formatBaseX = function (value, base, prefix, leftJustify, minWidth, precision, zeroPad) {
                // Note: casts negative numbers to positive ones
                var number = value >>> 0;
                prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || '';
                value = prefix + pad(number.toString(base), precision || 0, '0', false);
                return justify(value, prefix, leftJustify, minWidth, zeroPad);
            };
        
            // formatString()
            var formatString = function (value, leftJustify, minWidth, precision, zeroPad, customPadChar) {
                if (precision != null) {
                    value = value.slice(0, precision);
                }
                return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar);
            };
        
            // doFormat()
            var doFormat = function (substring, valueIndex, flags, minWidth, _, precision, type) {
                var number;
                var prefix;
                var method;
                var textTransform;
                var value;
        
                if (substring == '%%') {return '%';}
        
                // parse flags
                var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, customPadChar = ' ';
                var flagsl = flags.length;
                for (var j = 0; flags && j < flagsl; j++) {
                    switch (flags.charAt(j)) {
                        case ' ': positivePrefix = ' '; break;
                        case '+': positivePrefix = '+'; break;
                        case '-': leftJustify = true; break;
                        case "'": customPadChar = flags.charAt(j+1); break;
                        case '0': zeroPad = true; break;
                        case '#': prefixBaseX = true; break;
                    }
                }
        
                // parameters may be null, undefined, empty-string or real valued
                // we want to ignore null, undefined and empty-string values
                if (!minWidth) {
                    minWidth = 0;
                } else if (minWidth == '*') {
                    minWidth = +a[i++];
                } else if (minWidth.charAt(0) == '*') {
                    minWidth = +a[minWidth.slice(1, -1)];
                } else {
                    minWidth = +minWidth;
                }
        
                // Note: undocumented perl feature:
                if (minWidth < 0) {
                    minWidth = -minWidth;
                    leftJustify = true;
                }
        
                if (!isFinite(minWidth)) {
                    throw new Error('sprintf: (minimum-)width must be finite');
                }
        
                if (!precision) {
                    precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : undefined;
                } else if (precision == '*') {
                    precision = +a[i++];
                } else if (precision.charAt(0) == '*') {
                    precision = +a[precision.slice(1, -1)];
                } else {
                    precision = +precision;
                }
        
                // grab value using valueIndex if required?
                value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];
        
                switch (type) {
                    case 's': return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar);
                    case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad);
                    case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
                    case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
                    case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
                    case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase();
                    case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
                    case 'i':
                    case 'd':
                        number = parseInt(+value, 10);
                        prefix = number < 0 ? '-' : positivePrefix;
                        value = prefix + pad(String(Math.abs(number)), precision, '0', false);
                        return justify(value, prefix, leftJustify, minWidth, zeroPad);
                    case 'e':
                    case 'E':
                    case 'f':
                    case 'F':
                    case 'g':
                    case 'G':
                        number = +value;
                        prefix = number < 0 ? '-' : positivePrefix;
                        method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
                        textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
                        value = prefix + Math.abs(number)[method](precision);
                        return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform]();
                    default: return substring;
                }
            };
        
            return format.replace(regex, doFormat);
        }
        ,
        strip_tags: function (str, allowed_tags) {
            // Strips HTML and PHP tags from a string  
            // 
            // version: 909.322
            // discuss at: http://phpjs.org/functions/strip_tags
            // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   improved by: Luke Godfrey
            // +      input by: Pul
            // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   bugfixed by: Onno Marsman
            // +      input by: Alex
            // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +      input by: Marc Palau
            // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +      input by: Brett Zamir (http://brett-zamir.me)
            // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   bugfixed by: Eric Nagel
            // +      input by: Bobby Drake
            // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
            // +   bugfixed by: Tomasz Wesolowski
            // *     example 1: $P.strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i><b>');
            // *     returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
            // *     example 2: $P.strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
            // *     returns 2: '<p>Kevin van Zonneveld</p>'
            // *     example 3: $P.strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
            // *     returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
            // *     example 4: $P.strip_tags('1 < 5 5 > 1');
            // *     returns 4: '1 < 5 5 > 1'
            var key = '', allowed = false;
            var matches = [];
            var allowed_array = [];
            var allowed_tag = '';
            var i = 0;
            var k = '';
            var html = '';
        
            var replacer = function (search, replace, str) {
                return str.split(search).join(replace);
            };
        
            // Build allowes tags associative array
            if (allowed_tags) {
                allowed_array = allowed_tags.match(/([a-zA-Z0-9]+)/gi);
            }
        
            str += '';
        
            // Match tags
            matches = str.match(/(<\/?[\S][^>]*>)/gi);
        
            // Go through all HTML tags
            for (key in matches) {
                if (isNaN(key)) {
                    // IE7 Hack
                    continue;
                }
        
                // Save HTML tag
                html = matches[key].toString();
        
                // Is tag not in allowed list? Remove from str!
                allowed = false;
        
                // Go through all allowed tags
                for (k in allowed_array) {
                    // Init
                    allowed_tag = allowed_array[k];
                    i = -1;
        
                    if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+'>');}
                    if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+' ');}
                    if (i != 0) { i = html.toLowerCase().indexOf('</'+allowed_tag)   ;}
        
                    // Determine
                    if (i == 0) {
                        allowed = true;
                        break;
                    }
                }
        
                if (!allowed) {
                    str = replacer(html, "", str); // Custom replace. No regexing
                }
            }
        
            return str;
        }
    }; // end PHP_JS.prototype

    // 1) You must now instantiate PHP_JS yourself to use it (you don't need
    // "new" to do it, though it is slightly faster and better practice if you do
    // use "new").
    // You can do so like this:   var $P = PHP_JS();
    // 2) To pass in initial ini values without requiring ini_set() calls (see the
    // individual functions and
    // http://trac.phpjs.org/projects/phpjs/wiki/php_js_Global for
    // which ones are available), you can pass in the ini data as follows:
    // var $P = new PHP_JS({ini: {
    //     'date.timezone':'America/Chicago', // PHP ini's used in PHP.JS
    //     'phpjs.objectsAsArrays': true // custom PHP.JS ini's
    // }});
    // 3) If you place this namespace in a context like a JavaScript module
    // (e.g., for a Firefox extension) without access to the global
    // window object, you could instantiate in code which can obtain a
    // "window" object like this: var $P = PHP_JS({window:window});
    // This is not necessary for regular HTML JavaScript.
    this.PHP_JS = PHP_JS; // Make PHP_JS available outside of namespace
}());

PHPJS = new PHP_JS();